package top.maof.lightsearch.handle;

import lombok.extern.slf4j.Slf4j;
import top.maof.lightsearch.exception.NoMappingException;
import top.maof.lightsearch.map.*;
import top.maof.lightsearch.util.LightUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 处理器链
 */
@Slf4j
public class HandleChain implements Handle {

    private final static Handle KEY_HANDLE = new KeyHandle();
    private final static Handle SIMPLE_HANDLE = new SimpleHandle();
    private final static Handle CONVERTER_HANDLE = new ConverterHandle();

    private List<Handle> handles;

    private int position = 0;

    private Map<Class, Mapping> map = MappingPool.getPool();

    public HandleChain() {
        // 初始化处理器链
        handles = new ArrayList<>();
        handles.add(KEY_HANDLE);
        handles.add(SIMPLE_HANDLE);
        handles.add(CONVERTER_HANDLE);
    }

    public String fieldName(String typeValue, String propertyValue) {
        return LightUtils.fieldKey(typeValue, propertyValue);
    }


    public Mapping getMapping(Class clazz) throws NoMappingException {
        return MappingPool.getMapping(clazz);
    }


    public HandleChain addMapping(Class clazz, Mapping mapping) {
        this.map.put(clazz, mapping);
        return this;
    }


    public void add(Handle... handles) {
        List<Handle> list = Arrays.asList(handles);
        this.handles.addAll(list);
    }


    public HandleChain add(Handle handle) {
        this.handles.add(handle);
        return this;
    }

    public HandleChain add(int index, Handle handle) {
        this.handles.add(index, handle);
        return this;
    }


    @Override
    public void indexHandle(Entity entity, Index index, HandleChain handleChain) throws Exception {
        // 处理器链执行完毕
        if (position == handles.size()) {
            position = 0;
            return;
        }
        this.handles.get(position++).indexHandle(entity, index, handleChain);
    }


    @Override
    public void searchHandle(Entity entity, Index index, HandleChain handleChain) throws Exception {
        if (position == handles.size()) {
            position = 0;
            return;
        }
        this.handles.get(position++).searchHandle(entity, index, handleChain);
    }


    public void doIndex(Entity entity, Index index) throws Exception {
        this.indexHandle(entity, index, this);
    }


    public void doSearch(Entity entity, Index index) throws Exception {
        this.searchHandle(entity, index, this);
    }

}
